package com.way.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.way.CommonResult;
import com.way.constans.CommonConstants;
import com.way.util.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@Component
public class AuthFilter implements GlobalFilter, Ordered {

    private static final List<String> whiteList;

    private static final Logger log = LoggerFactory.getLogger(AuthFilter.class);

    @Autowired
    private RedisUtil redisUtil;

    static {
        whiteList = new ArrayList<>();
        whiteList.add("/auth/login");
        whiteList.add("/google/index");
        whiteList.add("/mall/weiXinMessage");
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String url = exchange.getRequest().getURI().getPath();
        log.info("url: {}",url);
        //白名单不鉴权
        if(whiteList.contains(url)) {
            return chain.filter(exchange);
        }
        String token = exchange.getRequest().getHeaders().getFirst("token");
        if(StringUtils.isBlank(token)) {
            return setUnauthorizedResponse(exchange);
        }
        log.info("token: {}",token);
        String userStr = redisUtil.get(CommonConstants.ACCESS_TOKEN + token).toString();
        if (org.apache.commons.lang.StringUtils.isBlank(userStr)) {
            return setUnauthorizedResponse(exchange);
        }
        JSONObject jo = JSONObject.parseObject(userStr);
        String userId = jo.getString("userId");
        if (StringUtils.isBlank(userId)) {
            return setUnauthorizedResponse(exchange);
        }
        log.info("user: {}",jo);
        // 设置userId到request里，后续根据userId，获取用户信息
        ServerHttpRequest mutableReq = exchange.getRequest().mutate().header(CommonConstants.CURRENT_ID, userId)
                .header(CommonConstants.CURRENT_USERNAME, jo.getString("loginName")).build();
        ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
        return chain.filter(mutableExchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }

    private Mono<Void> setUnauthorizedResponse(ServerWebExchange exchange) {
        ServerHttpResponse originalResponse = exchange.getResponse();
        originalResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
        originalResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        byte[] response;
        response = JSON.toJSONString(CommonResult.fail(HttpStatus.UNAUTHORIZED.value(), "token verify error")).getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = originalResponse.bufferFactory().wrap(response);
        return originalResponse.writeWith(Flux.just(buffer));
    }
}
